﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Medianamik.Core.SiteMap
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using Medianamik.Client.DAL;
    using Medianamik.Core;
    using System.Xml;
    using System.IO;

    namespace CampingQuebec.Logic.Utils
    {
        /// <summary>
        /// Génération de base d'un SiteMaps pour moteur de recherche, Protocole: http://www.sitemaps.org/
        /// </summary>
        public class SiteMapGenerator
        {
            #region [ Events ]

            public event UrlInsertion SiteMapBeforeInsertUrl;
            public delegate void UrlInsertion(Guid typeId, out List<string> urls);

            #endregion

            #region [ Properties ]

            private List<Guid> _listType;

            #endregion

            #region [ Methods ]

            public SiteMapGenerator(List<Guid> listType)
            {
                _listType = listType;
            }

            /// <summary>
            /// Générer le SiteIndex
            /// </summary>
            public void WriteXmlSiteMapIndex()
            {
                //Génération du XML
                HttpContext.Current.Response.ContentType = "text/xml";

                XmlTextWriter siteMap = new XmlTextWriter(HttpContext.Current.Response.OutputStream, System.Text.Encoding.UTF8);
                siteMap.Formatting = Formatting.Indented;
                siteMap.WriteStartDocument();
                siteMap.WriteStartElement("sitemapindex");
                siteMap.WriteAttributeString("xmlns", "http://www.sitemaps.org/schemas/sitemap/0.9");
                siteMap.WriteAttributeString("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
                siteMap.WriteAttributeString("xsi:schemaLocation", "http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd");

                _listType.ForEach(p =>
                {
                    siteMap.WriteStartElement("sitemap");
                    siteMap.WriteElementString("loc", String.Format("http://{0}/sitemaps.xml?type={1}", HttpContext.Current.Request.Url.Authority, p.ToString()));
                    siteMap.WriteEndElement();
                });

                siteMap.WriteEndElement();
                siteMap.Close();
            }

            /// <summary>
            /// Générer le sitemap
            /// </summary>
            /// <param name="typeId"></param>
            public void WriteXmlSiteMap(Guid typeId)
            {
                List<string> urlsFinal = new List<string>();
                bool addUrl = true;

                if (SiteMapBeforeInsertUrl != null)
                {
                    List<string> urls = null;
                    SiteMapBeforeInsertUrl(typeId, out urls);

                    if (urls != null)
                    {
                        urlsFinal.AddRange(urls);
                        addUrl = false;
                    }
                }

                // On ajoute toutes les urls
                if (addUrl)
                {
                    List<WebPage> pages = new SubSonic.Select().From<WebPage>()
                        .Where(WebPage.Columns.TypeId).Like(typeId.ToString())
                        .AndExpression(WebPage.Columns.Generation).IsEqualTo((int)Medianamik.Client.ContentState.Published)
                        .AndExpression(WebPage.Columns.NotDisplayInSiteMapsProtocole)
                        .IsNull().Or(WebPage.Columns.NotDisplayInSiteMapsProtocole)
                        .IsEqualTo(false).CloseExpression().ExecuteTypedList<WebPage>();

                    urlsFinal.AddRange(pages.Select(p => p.DefaultUrl.ToString()));
                }

                //Génération du XML
                HttpContext.Current.Response.ContentType = "text/xml";

                XmlTextWriter siteMap = new XmlTextWriter(HttpContext.Current.Response.OutputStream, System.Text.Encoding.UTF8);
                siteMap.Formatting = Formatting.Indented;
                siteMap.WriteStartDocument();
                siteMap.WriteStartElement("urlset");
                siteMap.WriteAttributeString("xmlns", "http://www.sitemaps.org/schemas/sitemap/0.9");
                siteMap.WriteAttributeString("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
                siteMap.WriteAttributeString("xsi:schemaLocation", "http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd");

                urlsFinal.ForEach(p =>
                {
                    siteMap.WriteStartElement("url");
                    siteMap.WriteElementString("loc", p);
                    siteMap.WriteEndElement();
                });

                siteMap.WriteEndElement();
                siteMap.Close();
            }

            #endregion
        }
    }

}
